
package JET.SA;

import JET.Centers.ControlCenter;
import JET.Centers.Graphics.GUICenter.UtilTabs;
import JET.Frames.DataModels.DataModelsFactory;
import JET.Scene;
import JET.StaticActions;
import JET.SwingUtils.TreeUtil;
import JET.UtilPanels.UPSceneInspector;
import JET.geom.Vec2d;
import JET.physics.Mass;
import JET.physics.RSpring;
import JET.physics.Spring;
import JET.physics.Wall;
import JET.physics.bodies.SpringBody;
import java.util.ArrayList;
import java.util.Collection;
import javax.swing.tree.TreePath;

/**
 *
 * @author 057Ry
 */
public class SA_Selection {

    private static ControlCenter CC = ControlCenter.getInstance();

    ////////////////////////////////////////////////////////////////////////////
    //   SELECTION - adding and removing stuff to and from selection group    //
    ////////////////////////////////////////////////////////////////////////////

    public synchronized static void addSpringBodyToSelection(SpringBody sb, Scene scene, boolean updateSceneTreeSelection) {
        Collection<Mass> massCol = sb.getMassListSync();
        synchronized(massCol) {
            for (Mass mass : massCol)
                SA_Selection.addMassToSelection(mass, scene, updateSceneTreeSelection);
        }

        for (Spring spring : sb.getSpringList()) {
            SA_Selection.addSpringToSelection(spring, scene, updateSceneTreeSelection);
        }
        for (RSpring rSpring : sb.getRSpringList()) {
            SA_Selection.addRSpringToSelection(rSpring, scene, updateSceneTreeSelection);
        }
        for (Wall wall : sb.getBorder().getWallList()) {
            SA_Selection.addWallToSelection(wall, scene, updateSceneTreeSelection);
        }
    }

    public synchronized static void addMassToSelection(Mass mass, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.addMass(mass);

        if (updateSceneTreeSelection) {
            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().addSelectionPath(TreeUtil.getObjectPath(mass, scene));
        }
    }

    public synchronized static void addMassesToSelection(Collection<Mass> massCol, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.addMasses(massCol);

        if (updateSceneTreeSelection) {
            TreePath[] paths = new TreePath[massCol.size()];
            int index = 0;

            for(Mass m : massCol) {
                paths[index++] = new TreePath(TreeUtil.getObjectPath(m, scene));
            }

            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().addSelectionPaths(paths);
        }
    }

    public synchronized static void removeMassFromSelection(Mass mass, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.removeMass(mass);

        if (updateSceneTreeSelection) {
            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().removeSelectionPath(TreeUtil.getObjectPath(mass, scene));
        }
    }

    public synchronized static void addSpringToSelection(Spring spring, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.addSpring(spring);

        if (updateSceneTreeSelection) {
            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().addSelectionPath(TreeUtil.getObjectPath(spring, scene));
        }
    }

    public synchronized static void addSpringsToSelection(Collection<Spring> springsCol, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.addSprings(springsCol);

        if (updateSceneTreeSelection) {
            TreePath[] paths = new TreePath[springsCol.size()];

            int index = 0;
            for(Spring s : springsCol) {
                paths[index++] = new TreePath(TreeUtil.getObjectPath(s, scene));
            }

            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().addSelectionPaths(paths);
        }
    }

    public synchronized static void removeSpringFromSelection(Spring spring, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.removeSpring(spring);

        if (updateSceneTreeSelection) {
            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().removeSelectionPath(TreeUtil.getObjectPath(spring, scene));
        }
    }

    public synchronized static void addRSpringToSelection(RSpring rSpring, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.addRSpring(rSpring);

        if (updateSceneTreeSelection) {
            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().addSelectionPath(TreeUtil.getObjectPath(rSpring, scene));
        }
    }

    public synchronized static void removeRSpringFromSelection(RSpring rSpring, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.removeRSpring(rSpring);

        if (updateSceneTreeSelection) {
            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().removeSelectionPath(TreeUtil.getObjectPath(rSpring, scene));
        }
    }

    public synchronized static void addWallToSelection(Wall wall, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.addWall(wall);

        if (updateSceneTreeSelection) {
            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().addSelectionPath(TreeUtil.getObjectPath(wall, scene));
        }
    }

    public synchronized static void removeWallFromSelection(Wall wall, Scene scene, boolean updateSceneTreeSelection) {
        scene.EC.selectionGroup.removeWall(wall);

        if (updateSceneTreeSelection) {
            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
            upSceneInspector.getSceneTree().removeSelectionPath(TreeUtil.getObjectPath(wall, scene));
        }
    }

    public synchronized static void clearSelection(Scene scene) {
        /*
        ArrayList<Mass> mlist = new ArrayList<Mass>(scene.EC.selectionGroup.getMassList());
        for (Mass mass : mlist)
            SA_Selection.removeMassFromSelection(mass, scene, true);
        mlist.clear();

        ArrayList<Spring> slist = new ArrayList<Spring>(scene.EC.selectionGroup.getSpringList());
        for (Spring spring : slist)
            SA_Selection.removeSpringFromSelection(spring, scene, true);
        slist.clear();

        ArrayList<RSpring> rslist = new ArrayList<RSpring>(scene.EC.selectionGroup.getRSpringList());
        for (RSpring rSpring : rslist)
            SA_Selection.removeRSpringFromSelection(rSpring, scene, true);
        rslist.clear();

        ArrayList<Wall> wlist = new ArrayList<Wall>(scene.EC.selectionGroup.getWallList());
        for (Wall wall : wlist)
            SA_Selection.removeWallFromSelection(wall, scene, true);
        wlist.clear();
         */
        scene.EC.selectionGroup.clear();

        UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
        upSceneInspector.getSceneTree().getSelectionModel().clearSelection();

        CC.GUIC.repaintAllSceneTabs();
    }

    public static void deleteSelectedObjects(Scene scene, boolean updateSceneTreeSelection) {

        ArrayList<Wall> wlist = new ArrayList<Wall>(scene.EC.selectionGroup.getWallListSync());
        for (Wall wall : wlist)
            SA_Wall.removeWallFromSpringBody(wall, scene, false);
        wlist.clear();

        ArrayList<Spring> slist = new ArrayList<Spring>(scene.EC.selectionGroup.getSpringList());
        for (Spring spring : slist) {
            switch(spring.getType()) {
                case Engine:
                    SA_Spring.removeSpringFromEngine(spring, scene);
                    break;
                case SceneItem:
                    SA_Spring.removeSpringFromSceneItem(spring, scene, false);
                    break;
                case SpringBody:
                    SA_Spring.removeSpringFromSpringBody(spring, scene, false);
                    break;
            }
        }
        slist.clear();

        ArrayList<RSpring> rslist = new ArrayList<RSpring>(scene.EC.selectionGroup.getRSpringListSync());
        for (RSpring rs : rslist) {
            switch(rs.getType()) {
                case Engine:
                    SA_RSpring.removeRSpringFromEngine(rs, scene);
                    break;
                case SceneItem:
                    SA_RSpring.removeRSpringFromSceneItem(rs, scene, false);
                    break;
                case SpringBody:
                    SA_RSpring.removeRSpringFromSpringBody(rs, scene, false);
                    break;
            }
        }
        rslist.clear();

        ArrayList<Mass> mlist = new ArrayList<Mass>(scene.EC.selectionGroup.getMassList());
        for (Mass mass : mlist) {
            SA_Mass.removeMassFromSpringBody(mass, scene, false);
        }
        mlist.clear();

        SA_Selection.clearSelection(scene);

        if (updateSceneTreeSelection)
            DataModelsFactory.getSceneTreeModel().fireWholeTreeChanged();
    }

    public synchronized static void zeroSelectedMassVelocities(Scene scene) {
        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
            mass.getVelocity().zero();
        }
    }

    public synchronized static void randomSelectedMassVelocities(Scene scene) {
        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
            Vec2d random = Vec2d.getRandomVectorInCircle(100);
            mass.setVelocity(random);
        }
    }
}
